package nbpMaven2.nbpMaven2;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XMLReaderClass implements IXMLReading {

	private static final String DATE_VALIDATION_PATTERN = "^[0-9]{1,6}$";

	// pobiera wartosc dla kazdej waluty w podanym dniu

	@Override
	public void getValueWithCountry(String xmlFile, Date date) {
		if (!xmlFile.equals("")) {
			try {
				URL url = new URL("http://www.nbp.pl" + xmlFile);
				DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
				Document doc = docBuilder.parse(url.openStream());
				String dibsCode = "";
				NodeList nLista = doc.getElementsByTagName("pozycja");
				DecimalFormatSymbols symbols = new DecimalFormatSymbols();
				symbols.setDecimalSeparator(',');
				String patt = "0.#";
				DecimalFormat df = new DecimalFormat(patt, symbols);
				df.setParseBigDecimal(true);
				BigDecimal bd = null;
				int id = 0;

				DBConnectionClass dbconn = new DBConnectionClass();

				for (int i = 0; i < nLista.getLength(); i++) {
					Node nNode = nLista.item(i);
					if (nNode.getNodeType() == Node.ELEMENT_NODE) {
						Element elem = (Element) nNode;
						bd = (BigDecimal) df.parse(dibsCode = elem.getElementsByTagName("kurs_sredni").item(0).getTextContent());
						id = dbconn.getCurrId(elem.getElementsByTagName("kod_waluty").item(0).getTextContent());

						if (id == 0) {
							dbconn.setCurr(elem.getElementsByTagName("nazwa_waluty").item(0).getTextContent(), elem.getElementsByTagName("kod_waluty").item(0).getTextContent());
							id = dbconn.getCurrId(elem.getElementsByTagName("kod_waluty").item(0).getTextContent());
						}

						if (dbconn.checkCurrInAvgTab(date, id) == false)
							dbconn.setCurrValue(date, bd, id);
					}
				}
			}

			catch (Exception ex) {
				throw new SomeException("There is some exception");
			}
		}
	}

	// pobiera konkretny plik xml
	@Override
	public String getXmlFile(Date date) throws DateIsNotCorrect, NoRateThisDay {
		// pobieranie XMLa
		// System.out.println("1");
		String info = "";
		try {
			// System.out.println(date);
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.add(Calendar.MONTH, 1);
			String year = (Integer.toString(cal.get(Calendar.YEAR))).substring(2, 4);
			String month = (Integer.toString(cal.get(Calendar.MONTH))).length() == 1 ? "0" + (Integer.toString(cal.get(Calendar.MONTH))) : (Integer.toString(cal.get(Calendar.MONTH)));
			String day = (Integer.toString(cal.get(Calendar.DAY_OF_MONTH))).length() == 1 ? "0" + (Integer.toString(cal.get(Calendar.DAY_OF_MONTH))) : (Integer.toString(cal.get(Calendar.DAY_OF_MONTH)));
			String recivedDate = year + month + day;
			// System.out.println(recivedDate);
			Pattern firstPatt = Pattern.compile(DATE_VALIDATION_PATTERN);
			Matcher firstMatch = firstPatt.matcher(recivedDate);
			boolean gotIt = firstMatch.matches() ? true : false;
			// System.out.println("2");
			if (!gotIt)
				throw new DateIsNotCorrect("This date is not correct! The valid pattern is: dd/mm/yyyy");

			else {
				URL link = new URL("http://www.nbp.pl/kursy/xml/dir.txt");
				// System.out.println("3");
				BufferedReader in = null;
				URLConnection conn = null;
				conn = link.openConnection();
				conn.connect();
				in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
				String inputline = null;
				boolean find = false;
				String nazwa = null;
				// System.out.println("4");
				while ((inputline = in.readLine()) != null) {
					if (inputline.length() > 0 && inputline.charAt(0) == 'a') {
						Pattern patern = Pattern.compile(recivedDate);
						Matcher matchdata = patern.matcher(inputline);
						find = matchdata.find();
						if (find) {
							// System.out.println("5");
							info = "/kursy/xml/" + inputline + ".xml";
							break;
						}
					}
				}

				if (info.equals(""))
					throw new NoRateThisDay("Brak kurs�w z tego dnia!");

			}
		} catch (Exception ex) {
			// throw new
			// SomeException("There is some exception with XML Parse");
		}
		return info;

	}

	// pobiera srednia wartosc walut i zwraca min/max

	@Override
	public CurrencyInfoClass getSomeValue(String xmlName, String type) throws ClassNotFoundException, NullPointerException {
		CurrencyInfoClass obj = null;

		if (xmlName.equals("") == false) {
			try {
				// System.out.println(xmlName);
				URL url = new URL("http://www.nbp.pl" + xmlName);
				DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
				Document doc = docBuilder.parse(url.openStream());

				String dibsCode = "";
				String valOfCurr = "";
				BigDecimal bd = null;
				String dibsName = "";

				NodeList nLista = doc.getElementsByTagName("pozycja");
				DecimalFormatSymbols symbols = new DecimalFormatSymbols();
				symbols.setDecimalSeparator(',');
				String patt = "0.#";
				DecimalFormat df = new DecimalFormat(patt, symbols);
				df.setParseBigDecimal(true);
				List<BigDecimal> myList = new ArrayList<BigDecimal>();

				for (int i = 0; i < nLista.getLength(); i++) {
					Node nNode = nLista.item(i);
					if (nNode.getNodeType() == Node.ELEMENT_NODE) {
						Element elem = (Element) nNode;
						myList.add((BigDecimal) df.parse(dibsCode = elem.getElementsByTagName("kurs_sredni").item(0).getTextContent()));
					}
				}

				switch (type) {
				case ("MAX"):
					bd = Collections.max(myList);
					valOfCurr = bd.toString();
					dibsName = getCurrName(xmlName, valOfCurr);
					obj = new CurrencyInfoClass(dibsName, bd);
					break;

				case ("MIN"):
					bd = Collections.min(myList);
					valOfCurr = bd.toString();
					dibsName = getCurrName(xmlName, valOfCurr);
					obj = new CurrencyInfoClass(dibsName, bd);
					break;
				}
			}

			catch (Exception ex) {
				throw new SomeException("There is some exception with XML Parse");
			}
		}

		else
			obj = new CurrencyInfoClass();
		return obj;
	}

	@Override
	public String getCurrName(String xmlName, String valOfCurr) {
		String nameOfCurr = "";
		try {
			URL url = new URL("http://www.nbp.pl" + xmlName);
			DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
			Document doc = docBuilder.parse(url.openStream());
			String sendVal = valOfCurr;
			String dibsCode = "";
			NodeList nLista = doc.getElementsByTagName("pozycja");

			for (int i = 0; i < nLista.getLength(); i++) {
				Node nNode = nLista.item(i);
				if (nNode.getNodeType() == Node.ELEMENT_NODE) {
					Element elem = (Element) nNode;
					dibsCode = elem.getElementsByTagName("kurs_sredni").item(0).getTextContent();
					char[] dibs = dibsCode.toCharArray();
					dibs[1] = '.';
					dibsCode = String.valueOf(dibs);

					if (sendVal.equals(dibsCode)) {
						nameOfCurr = elem.getElementsByTagName("kod_waluty").item(0).getTextContent();
					}
				}
			}
		}

		catch (Exception ex) {
			throw new SomeException("There is some exception!");
		}
		return nameOfCurr;
	}
}
